using System.IO;
using System.Collections.Generic;

using UnityEngine;

namespace Game {

    /// <summary>
    /// 文件修改监听
    /// 
    /// 游戏运行中，如果注册的文件发生了变化，抛出事件（程序可以选择重新加载相关文件，这样可以提升调试/开发效率）
    /// 注：只在Editor模式下有效
    /// </summary>
    public class FileModify : MonoBehaviour {
#if UNITY_EDITOR
        /// 监听时间周期
        private static readonly float DeltaTime = 0.25f;

        private class FileInfo {
            public string path = "";
            public long lastModifyTime = 0;
            public System.Action<string> pChangeCall = null;

            public FileInfo(string _path, System.Action<string> _call) {
                pChangeCall = _call;
                path = _path;
                lastModifyTime = File.GetLastWriteTime(path).ToFileTime();
            }
        }

        private static List<FileInfo> files = new List<FileInfo>();
#endif

        // 注册的路径必须是Asserts开头的全路径。不然更改后没法ImportAsset
        public static void Register(string path, System.Action<string> pChange) {
#if UNITY_EDITOR
            for (int i = 0; i < files.Count; ++i) {
                if (files[i].path == path) {
                    files[i].pChangeCall = pChange;
                    return;
                }
            }
            files.Add(new FileInfo(path, pChange));
#endif
        }

        public static void UnRegister(string path) {
#if UNITY_EDITOR
            for (int i = 0; i < files.Count; ++i) {
                if (files[i].path == path) {
                    files.RemoveAt(i);
                    return;
                }
            }
#endif
        }

#if UNITY_EDITOR
        private void Update() {
            if (Time.realtimeSinceStartup - lastCheckTime >= DeltaTime) {
                lastCheckTime = Time.realtimeSinceStartup;

                for (int i = files.Count - 1; i >= 0; --i) {
                    var one = files[i];
                    long time = File.GetLastWriteTime(one.path).ToFileTime();
                    if (time != one.lastModifyTime) {
                        one.lastModifyTime = time;
                        UnityEditor.AssetDatabase.ImportAsset(one.path);
                        one.pChangeCall.Invoke(one.path);
                    }
                }
            }
        }
        private float lastCheckTime = 0;
#endif
    }
}